/*
 *  Arrow
 *
 *  Created by David Giovannini on 1/5/07.
 *  Copyright 2007 Software by Jove. All rights reserved.
 *
 */
 
#include "SBJ/Arrow/Publication.h"
#include "SBJ/Arrow/MsgProxy.h"

#include <typeinfo>

namespace SBJ
{

namespace Arrow
{

Publication::Publication( const std::string& key, const IExceptionObserver::Ptr& excObserver )
: m_key( key )
, m_excObserver( excObserver )
{
}
	
Publication::~Publication( void )
{
	KeyedMsgProxys::iterator iter( m_msgProxys.begin() );
	while ( iter != m_msgProxys.end() )
	{
		delete iter->second;
		++iter;
	}

	KeyedTopics::iterator iter2( m_topics.begin() );
	while ( iter2 != m_topics.end() )
	{
		delete iter2->second;
		++iter2;
	}
}

Topic
Publication::getTopic( const std::string& topicKey ) const
{
	boost::mutex::scoped_lock lock( m_guard );

	if ( m_msgProxys.size() == 1 ) 
	{
		if ( topicKey.empty() == true )
		{
			return Topic( this, m_msgProxys.begin()->second );
		}
		else
		{
			KeyedTopics::const_iterator iter = m_topics.find( topicKey );
			if ( iter != m_topics.end() && iter->second->use > 0 )
			{
				return Topic( this, iter->second );
			}
		}
	}
	return Topic();
}

Topic
Publication::makeTopic( const MsgProxy* MsgProxy, const std::string& topicKey )
{
	if ( MsgProxy != 0 )
	{
		std::pair< KeyedTopics::iterator, bool > result = m_topics.insert( std::make_pair( topicKey, static_cast< Topic::SharedData* >( 0 ) ) );
		if ( result.second == true )
		{
			result.first->second = new Topic::SharedData( MsgProxy, topicKey );
			result.first->second->hash = reinterpret_cast< size_t >( result.first->second );
		}
		return Topic( this, result.first->second );
	}
	return Topic();
}

const MsgProxy*
Publication::getMsgProxy( void ) const
{
	if ( m_msgProxys.size() != 1 )
		throw std::logic_error( "Publication can only have one type for getMsgProxy" );
	return m_msgProxys.begin()->second;
}

}

}